package com.jwsoft.manager.core.integration.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.data.core.util.PagerUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressSchoolRelationAddVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressTreeSchoolRemoveVO;
import com.jwsoft.manager.common.vo.eduEnrollmenBrochure.EnrollmenBrochureVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.model.*;
import com.jwsoft.manager.core.dao.service.*;
import com.jwsoft.manager.core.integration.eduAddressTree.EduAddressTreeIntegration;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.convert.Convert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.bifang.engine.assistant.core.exception.AppException;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.jwsoft.manager.common.vo.eduAddressSchoolReplace.EduAddressSchoolReplaceVO;
import com.jwsoft.manager.common.vo.eduAddressSchoolReplace.EduAddressSchoolReplaceKeyVO;
import com.jwsoft.manager.common.vo.eduAddressSchoolReplace.EduAddressSchoolReplaceQueryVO;
import com.jwsoft.manager.core.integration.EduAddressSchoolReplaceIntegration;

/**
 * 地址学区替换表业务实现类
 *
 * @author zhiyuan
 * @since 2024-03-18
 */
@ApiService(funcCode = "addressSchoolReplace", title = "地址学区替换表")
public class EduAddressSchoolReplaceIntegrationImpl implements EduAddressSchoolReplaceIntegration {

    @Autowired
    public EduAddressSchoolReplaceService eduAddressSchoolReplaceService;

    @Autowired
    private EduAddressService addressService;

    @Autowired
    private EduSchoolService schoolService;

    @Autowired
    private EduAddressTreeService addressTreeService;

    @Autowired
    private EduAddressTreeSchoolService addressTreeSchoolService;


    @Autowired
    private EduAddressSchoolService aduAddressSchoolService;

    @Autowired
    private EduAddressTreeIntegration addressTreeIntegration;

    @Autowired
    private EduAddressSchoolService eduAddressSchoolService;

    @Autowired
    private EduAddressTreeSchoolService treeSchoolService;

    @Override
    @OpApi(funcCode = "addressSchoolReplace0001", title = "地址学区替换表分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduAddressSchoolReplaceVO> getList(EduAddressSchoolReplaceQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        List<EduAddressSchoolReplace> list = eduAddressSchoolReplaceService.list();
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduAddressSchoolReplace> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduAddressSchoolReplaceVO> resultList = Convert.toList(EduAddressSchoolReplaceVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(DemoDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "addressSchoolReplace0002", title = "地址学区替换表根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduAddressSchoolReplaceVO getById(EduAddressSchoolReplaceKeyVO vo) {
        EduAddressSchoolReplace entity = eduAddressSchoolReplaceService.getById(vo.getReplaceId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduAddressSchoolReplaceVO result = Convert.convert(EduAddressSchoolReplaceVO.class, entity);
        return result;
    }
    /** 保存前统一校验*/
    @Override
    @OpApi(funcCode = "addressSchoolReplace0003", title = "地址学区替换表保存前校验", funcType = FuncTypeEnum.other ,checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduAddressSchoolReplaceVO vo) {
        //主键为空为新增校验

        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "addressSchoolReplace0004", title = "地址学区替换表新增", funcType = FuncTypeEnum.insert)
    @Transactional
    public EduAddressSchoolReplaceVO add(EduAddressSchoolReplaceVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduAddressSchoolReplace entity = Convert.convert(EduAddressSchoolReplace.class, vo);
        eduAddressSchoolReplaceService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setReplaceId(entity.getReplaceId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "addressSchoolReplace0005", title = "地址学区替换表修改", funcType = FuncTypeEnum.update)
    @Transactional
    public EduAddressSchoolReplaceVO edit(EduAddressSchoolReplaceVO vo) {
        if (ObjectUtils.isEmpty(vo.getReplaceId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduAddressSchoolReplace oldEntity = eduAddressSchoolReplaceService.getById(vo.getReplaceId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduAddressSchoolReplace entity = Convert.convert(EduAddressSchoolReplace.class, vo);
        eduAddressSchoolReplaceService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "addressSchoolReplace0006", title = "地址学区替换表根据主键删除", funcType = FuncTypeEnum.delete)
    @Transactional
    public void del(EduAddressSchoolReplaceKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getReplaceId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduAddressSchoolReplace entity = eduAddressSchoolReplaceService.getById(vo.getReplaceId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduAddressSchoolReplaceService.removeById(vo.getReplaceId());
    }

    @Override
    @OpApi(funcCode = "addressSchoolReplace0007", title = "地址学区替换表修改", funcType = FuncTypeEnum.other,checkPrivilege = BoolEnum.FALSE)
    public void addressSchoolReplace(EduAddressSchoolReplaceVO vo) {
        //1，先查出待处理的数据
        QueryWrapper<EduAddressSchoolReplace> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddressSchoolReplace::getStatus,"1")
                .isNotNull(EduAddressSchoolReplace::getOldSchoolId)
                .isNotNull(EduAddressSchoolReplace::getAddressId);
        List<EduAddressSchoolReplace> list = eduAddressSchoolReplaceService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
           return;
        }

        //处理数据
        for (EduAddressSchoolReplace eduAddressSchoolReplace : list) {
            executeReplace(eduAddressSchoolReplace);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void executeReplace(EduAddressSchoolReplace eduAddressSchoolReplace) {
        //先查询出来，进行替换
        QueryWrapper<EduAddressSchool> schoolQueryWrapper  = new QueryWrapper<>();
        schoolQueryWrapper.lambda().eq(EduAddressSchool::getSchoolId,eduAddressSchoolReplace.getOldSchoolId())
                .eq(EduAddressSchool::getDel,BoolEnum.FALSE.getType())
                .eq(EduAddressSchool::getAddressId,eduAddressSchoolReplace.getAddressId());
        List<EduAddressSchool> eduAddressSchools = eduAddressSchoolService.list(schoolQueryWrapper);
        //如果为空
        if (ObjectUtils.isEmpty(eduAddressSchools)) {
            eduAddressSchoolReplace.setStatus("3");
            eduAddressSchoolReplace.setHandleRemark("edu_address_school表中不存在与学校关联数据！");
            eduAddressSchoolReplaceService.updateById(eduAddressSchoolReplace);
        }else if (eduAddressSchools.size() > 1){
            eduAddressSchoolReplace.setStatus("3");
            eduAddressSchoolReplace.setHandleRemark("edu_address_school表中存在多条（地址id，学校id）关联，数据异常，无法进行替换，请联系管理员处理！");
            eduAddressSchoolReplaceService.updateById(eduAddressSchoolReplace);
            return;
        }else if (eduAddressSchools.size() == 1){
            //有且仅有一条
            EduAddressSchool eduAddressSchool = eduAddressSchools.get(0);
            //将数据添加到取消关联列表中
            if (eduAddressSchoolReplace.getTreeId() == null){
                eduAddressSchoolReplace.setStatus("2");
                eduAddressSchoolReplace.setHandleRemark("地址树未解析");
                eduAddressSchoolReplaceService.updateById(eduAddressSchoolReplace);
            }
            //删除关联数据
            eduAddressSchoolService.removeById(eduAddressSchool.getAddressSchoolId());

            //如果替换学校存在，就进行替换，
            eduAddressSchoolReplace.setStatus("2");
            if (StringUtils.isBlank(eduAddressSchoolReplace.getNewSchoolName())){
                eduAddressSchoolReplace.setHandleRemark("已删除原学校关联，new_school_name 为空");
            }else{
                //判断数据库是否有数据
                QueryWrapper<EduAddressSchool> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda()
                        .eq(EduAddressSchool::getAddressId, eduAddressSchoolReplace.getAddressId())
                        .eq(EduAddressSchool::getSchoolId, eduAddressSchoolReplace.getNewSchoolId());
                EduAddressSchool addressSchool = eduAddressSchoolService.getOne(queryWrapper, false);
                if (!ObjectUtils.isEmpty(addressSchool)){
                    eduAddressSchoolReplace.setAddressSchoolId(addressSchool.getAddressSchoolId());
                    eduAddressSchoolReplace.setHandleRemark("已替换edu_address_school关联");
                }else{
                    //替换关联数据
                    eduAddressSchool.setAddressSchoolId(null);
                    eduAddressSchool.setSchoolId(eduAddressSchoolReplace.getNewSchoolId());
                    eduAddressSchool.setSchoolName(eduAddressSchoolReplace.getNewSchoolName());
                    eduAddressSchool.setAuthRemarks(eduAddressSchoolReplace.getOldSchoolName()+"替换学区为:"+eduAddressSchoolReplace.getNewSchoolName());
                    eduAddressSchoolService.save(eduAddressSchool);
                    eduAddressSchoolReplace.setAddressSchoolId(eduAddressSchool.getAddressSchoolId());
                    eduAddressSchoolReplace.setHandleRemark("已替换edu_address_school关联");
                }
            }
        }

        //取消关联方法
        removeSchoolRelation(eduAddressSchoolReplace);

        //关联方法
        addSchoolRelation(eduAddressSchoolReplace);

        //修改状态
        eduAddressSchoolReplaceService.updateById(eduAddressSchoolReplace);


    }

    private void addSchoolRelation(EduAddressSchoolReplace eduAddressSchoolReplace) {
        if (eduAddressSchoolReplace.getTreeId() == null){
            return;
        }
        if (StringUtils.isBlank(eduAddressSchoolReplace.getNewSchoolId())){
            eduAddressSchoolReplace.setHandleRemark("没有需要替换的学校数据");
            eduAddressSchoolReplace.setStatus("2");
            return;
        }
        EduAddressSchoolRelationAddVO addVO = new EduAddressSchoolRelationAddVO();
        List<EduSchoolVO> schoolVOS = new ArrayList<>();
        if (StringUtils.isNotBlank(eduAddressSchoolReplace.getNewSchoolId())){
            EduSchoolVO detail = schoolService.getDetail(eduAddressSchoolReplace.getNewSchoolId());
            schoolVOS.add(detail);
            addVO.setSchoolList(schoolVOS);
            addVO.setHandleChildFlag(BoolEnum.FALSE.getType());
            addVO.setTreeId(eduAddressSchoolReplace.getTreeId());
            try {
                addressTreeIntegration.addSchoolRelation(addVO);
                eduAddressSchoolReplace.setStatus("2");
                eduAddressSchoolReplace.setHandleRemark("edu_address_tree_school新学区关联成功");
                if (StringUtils.isBlank(eduAddressSchoolReplace.getAddressSchoolId())){
                    QueryWrapper<EduAddressSchool> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda()
                            .eq(EduAddressSchool::getAddressId, eduAddressSchoolReplace.getAddressId())
                            .eq(EduAddressSchool::getSchoolId, eduAddressSchoolReplace.getNewSchoolId());
                    EduAddressSchool addressSchool = eduAddressSchoolService.getOne(queryWrapper, false);
                    if (ObjectUtils.isEmpty(addressSchool)){
                        eduAddressSchoolReplace.setAddressSchoolId(addressSchool.getAddressSchoolId());
                        eduAddressSchoolReplace.setStatus("3");
                        eduAddressSchoolReplace.setHandleRemark("edu_address_tree_school关联失败");
                    }else{
                        eduAddressSchoolReplace.setAddressSchoolId(addressSchool.getAddressSchoolId());
                        eduAddressSchoolReplace.setStatus("2");
                        eduAddressSchoolReplace.setHandleRemark("edu_address_tree_school新学区关联成功");
                    }
                }
            } catch (Exception e) {
                String esMsg = e.getMessage().length() < 200 ? e.getMessage() : e.getMessage().substring(0, 200);
                eduAddressSchoolReplace.setStatus("3");
                eduAddressSchoolReplace.setHandleRemark("edu_address_tree_school新学区关联失败:"+esMsg);
            }
        }
    }

    private void removeSchoolRelation(EduAddressSchoolReplace eduAddressSchoolReplace) {
        if (eduAddressSchoolReplace.getTreeId() == null){
            return;
        }
        //查询出叶子节点和学校关联数据
        QueryWrapper<EduAddressTreeSchool> treeSchoolQueryWrapper = new QueryWrapper<>();
        treeSchoolQueryWrapper.lambda()
                .eq(EduAddressTreeSchool::getSchoolId,eduAddressSchoolReplace.getOldSchoolId())
                .eq(EduAddressTreeSchool::getTreeId,eduAddressSchoolReplace.getTreeId())
                .eq(EduAddressTreeSchool::getDel,BoolEnum.FALSE.getType());
        List<EduAddressTreeSchool> addressTreeSchoolList = addressTreeSchoolService.list(treeSchoolQueryWrapper);
        if (CollectionUtils.isEmpty(addressTreeSchoolList)){
            return;
        }
        List<Long> treeSchoolIds = addressTreeSchoolList.stream().map(EduAddressTreeSchool::getId).collect(Collectors.toList());
        EduAddressTreeSchoolRemoveVO removeVO = new EduAddressTreeSchoolRemoveVO();
        removeVO.setTreeId(eduAddressSchoolReplace.getTreeId());
        removeVO.setIds(treeSchoolIds);
        removeVO.setHandleChildFlag(BoolEnum.FALSE.getType());

        //取消地址书节点关联
        try {
            addressTreeIntegration.removeSchoolRelation(removeVO);
            eduAddressSchoolReplace.setStatus("2");
            eduAddressSchoolReplace.setHandleRemark("edu_address_tree_school取消关联成功");
        } catch (Exception e) {
            String esMsg = e.getMessage().length() < 200 ? e.getMessage() : e.getMessage().substring(0, 200);
            eduAddressSchoolReplace.setStatus("3");
            eduAddressSchoolReplace.setHandleRemark("edu_address_tree_school取消关联失败:"+esMsg);
        }

    }

    @Override
    @Transactional
    @OpApi(funcCode = "addressSchoolReplace0008", title = "替换信息补全", funcType = FuncTypeEnum.update,checkPrivilege = BoolEnum.FALSE)
    public void addressInfoComplement(EduAddressSchoolReplaceVO vo) {
        //查出待处理待补全的数据
        QueryWrapper<EduAddressSchoolReplace> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddressSchoolReplace::getStatus,BoolEnum.FALSE.getType())
                .isNotNull(EduAddressSchoolReplace::getOldSchoolName)
                .isNotNull(EduAddressSchoolReplace::getAddressName);
        List<EduAddressSchoolReplace> list = eduAddressSchoolReplaceService.list(queryWrapper);
        if (ObjectUtils.isEmpty(list)) {
            return;
        }

        List<String> addressNames = list.stream().map(EduAddressSchoolReplace::getAddressName).collect(Collectors.toList());
        //根据地址名，查出地址id信息
        QueryWrapper<EduAddress> addressWrapper = new QueryWrapper<>();
        addressWrapper.lambda().in(EduAddress::getAddressName,addressNames);
        List<EduAddress> addressList = addressService.list(addressWrapper);
        //地址名和地址信息映射
        Map<String, EduAddress> addressMap =
                addressList.stream().collect(Collectors.toMap(EduAddress::getAddressName,EduAddress ->EduAddress));
        //根据学校名称，查出学校信息
        List<String> schoolNames = list.stream()
                .flatMap(s -> Stream.of(s.getOldSchoolName(), s.getNewSchoolName()))
                .collect(Collectors.toList());
        QueryWrapper<EduSchool> schoolWrapper = new QueryWrapper<>();
        schoolWrapper.lambda().in(EduSchool::getSchoolName,schoolNames);
        List<EduSchool> schoolList = schoolService.list(schoolWrapper);
        if (ObjectUtils.isEmpty(schoolList)){
            List<Long> replaceIds = list.stream().map(EduAddressSchoolReplace::getReplaceId).collect(Collectors.toList());
            //处理失败
            UpdateWrapper<EduAddressSchoolReplace> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().in(EduAddressSchoolReplace::getAddressId,replaceIds)
                    .set(EduAddressSchoolReplace::getStatus,3)
                    .set(EduAddressSchoolReplace::getHandleTime,new Date())
                    .set(EduAddressSchoolReplace::getHandleRemark,"学校信息不存在,请检查学校名称是否和数据库配置的school_name一致");
            eduAddressSchoolReplaceService.update(updateWrapper);
            return;
        }
        //学校map信息
        Map<String, EduSchool> schoolMap = schoolList.stream()
                .collect(Collectors.toMap(EduSchool::getSchoolName,EduSchool ->EduSchool));

        List<EduAddressSchoolReplace> addressSchoolReplaces = list.stream().map(item -> {
            if (StringUtils.isEmpty(item.getAddressId())) {
                //地址信息不存在，需要补全
                EduAddress address = addressMap.get(item.getAddressName());
                if (ObjectUtils.isEmpty(address)) {
                    //地址信息不存在，处理失败
                    item.setHandleTime(new Date());
                    item.setHandleRemark("地址信息不存在,请检查地址名称是否和数据库配置的address_name一致");
                    item.setStatus("3");
                    return item;
                }
                item.setAddressId(address.getAddressId());
                item.setTreeId(address.getAddressTreeId());
            }

            if (StringUtils.isEmpty(item.getOldSchoolId())) {
                EduSchool school = schoolMap.get(item.getOldSchoolName());
                if (ObjectUtils.isEmpty(school)) {
                    //学校信息不存在，处理失败
                    item.setHandleRemark(item.getOldSchoolName()+":原始学校名字有误,请检查学校名称是否和数据库配置的school_name一致");
                    item.setHandleTime(new Date());
                    item.setStatus("3");
                    return item;
                }
                item.setOldSchoolId(school.getOrgId());
            }

            if (StringUtils.isEmpty(item.getNewSchoolId())) {
                //如果替换学校名字不存在，不需要处理，存在就处理
                if(!ObjectUtils.isEmpty(item.getNewSchoolName())){
                    EduSchool school = schoolMap.get(item.getNewSchoolName());
                    if (ObjectUtils.isEmpty(school)) {
                        //学校信息不存在，处理失败
                        item.setHandleRemark(item.getNewSchoolName()+":替换学校名字有误,请检查学校名称是否和数据库配置的school_name一致");
                        item.setHandleTime(new Date());
                        item.setStatus("3");
                        return item;
                    }
                    item.setNewSchoolId(school.getOrgId());
                }
            }
            item.setStatus("1");
            item.setHandleRemark("替换信息补全");
            return item;
        }).collect(Collectors.toList());

        //批量修改
        eduAddressSchoolReplaceService.updateBatchById(addressSchoolReplaces);
    }
}
